/*
 * tp boole
 */
package boole.circuit;

import boole.application.vue.VueComposant;
import boole.port.PortEntree;
import boole.port.PortSortie;
import boole.port._PortEntree;
import boole.port._PortSortie;
import boole.port.exception.PortAlreadyConnectedException;
import boole.utils.StatusUnknownException;
import java.util.HashMap;
import java.util.Map;
import java.util.Observable;

/**
 * @author Rémi PIOTAIX <remi.piotaix@gmail.com>
 * @author Thomas Nds nds.thomas@gmail.com
 * @author Morgan Bidois
 */
public abstract class Composant extends Observable implements _Composant {

    private Map<Integer, _PortEntree> portEntrees;
    private Map<Integer, _PortSortie> portSorties;

    public Composant() {
        portEntrees = new HashMap();
        portSorties = new HashMap();
        for (int i = 1; i <= this.getNombreEntrees(); i++) {
            this.portEntrees.put(i, new PortEntree(this));
        }
        for (int i = 1; i <= this.getNombreSorties(); i++) {
            this.portSorties.put(i, new PortSortie(this));
        }
    }

    @Override
    public void setStatut(String statut) {
        throw new StatusUnknownException(statut);
    }

    @Override
    public _PortSortie getSortie(int identifiant) {
        return this.portSorties.get(identifiant);
    }

    @Override
    public _PortEntree getEntree(int identifiant) {
        return this.portEntrees.get(identifiant);
    }

    @Override
    public void connectSortieTo(int num, _PortOwner cible, int numPortCible) {
        try {
            _PortSortie sortie = this.getSortie(num);
            _PortEntree entreeCible = cible.getEntree(numPortCible);
            sortie.connect(entreeCible);
            entreeCible.connect(sortie);

        } catch (PortAlreadyConnectedException pace) {
            System.out.println("Le port numero " + num + " est deja connecte a  " + cible);
            throw pace;
        }
    }

    @Override
    public boolean isValid() {
        for (_PortSortie ps : this.portSorties.values()) {
            if (!ps.isValid()) {
                return false;
            }
        }
        for (_PortEntree pe : this.portEntrees.values()) {
            if (!pe.isValid()) {
                return false;
            }
        }
        return true;
    }
    
    public abstract VueComposant getView();

    @Override
    public void calcul() {
        setChanged();
        notifyObservers();
    }
    
    

}
